
package com.eyedog.video.http;

import android.text.TextUtils;
import android.util.Log;

import com.eyedog.library.utils.MD5Util;
import com.eyedog.video.constant.Constants;
import com.eyedog.video.entity.ADVEntity;
import com.eyedog.video.entity.ApiEntity;
import com.eyedog.video.entity.CustomerEntity;
import com.eyedog.video.entity.ProfileEntity;
import com.eyedog.video.entity.RespEntity;
import com.wallj.videolibrary.player.WaterMarkEntity;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class HttpClient {
    private final String TAG = "HttpClient";

    enum Instance {
        INSTANCE;

        HttpClient client;

        Instance() {
            client = new HttpClient();
        }
    }

    private HttpClient() {
        init(Constants.BASE_URL);
        mHasApiRequested = false;
        mIsRequestingApi = false;
    }

    public static HttpClient getInstance() {
        return Instance.INSTANCE.client;
    }

    private String baseUrl;

    private Retrofit retrofit;

    private boolean mIsRequestingApi = false, mHasApiRequested = false;

    private Object lock = new Object();

    private List<ICallback<ApiEntity>> apiListeners = new ArrayList<>();

    public void init(String baseurl) {
        if (!TextUtils.equals(baseUrl, baseurl) || retrofit == null) {
            this.baseUrl = baseurl;
            retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(baseurl).build();
        }
    }

    private String signString(String timeStamp) {
        return MD5Util.MD5(timeStamp + Constants.appID + Constants.secretKey);
    }

    private String getTimeStamp() {
        return System.currentTimeMillis() + "";
    }

    public void requestApi(final ICallback<ApiEntity> callback) {
        if (isRequestingApi()) {
            apiListeners.add(callback);
            return;
        }
        synchronized (lock) {
            mIsRequestingApi = true;
        }
        IApiService apiService = retrofit.create(IApiService.class);
        String timestamp = getTimeStamp();
        apiService.getApiUrl(timestamp, Constants.appID, signString(timestamp))
                .enqueue(new Callback<RespEntity<ApiEntity>>() {
                    @Override
                    public void onResponse(Call<RespEntity<ApiEntity>> call,
                            Response<RespEntity<ApiEntity>> response) {
                        if (response.isSuccessful()) {
                            RespEntity<ApiEntity> respEntity = response.body();
                            if (respEntity != null && respEntity.data != null) {
                                init(respEntity.data.url + "/");
                                HttpClientVideo.getInstance().init(respEntity.data.movie_url + "/");
                                mHasApiRequested = true;
                                callback.onLoadSuccess(respEntity.data);
                                for (ICallback<ApiEntity> apiCallback : apiListeners) {
                                    apiCallback.onLoadSuccess(respEntity.data);
                                }
                            } else {
                                callback.onLoadFailed("empty data");
                                for (ICallback<ApiEntity> apiCallback : apiListeners) {
                                    apiCallback.onLoadFailed("empty data");
                                }
                            }
                        } else {
                            callback.onLoadFailed("response not success");
                            for (ICallback<ApiEntity> apiCallback : apiListeners) {
                                apiCallback.onLoadFailed("response not success");
                            }
                        }
                        synchronized (lock) {
                            mIsRequestingApi = false;
                        }
                        apiListeners.clear();
                    }

                    @Override
                    public void onFailure(Call<RespEntity<ApiEntity>> call, Throwable t) {
                        callback.onLoadFailed("response onFailure " + t.getMessage());
                        for (ICallback<ApiEntity> apiCallback : apiListeners) {
                            apiCallback.onLoadFailed("response onFailure " + t.getMessage());
                        }
                        synchronized (lock) {
                            mIsRequestingApi = false;
                        }
                        apiListeners.clear();
                    }
                });
    }

    public boolean isRequestingApi() {
        synchronized (lock) {
            return mIsRequestingApi;
        }
    }

    private void _requestAdv(final ICallback<List<ADVEntity>> callback) {
        IAdvService advService = retrofit.create(IAdvService.class);
        String time = getTimeStamp();
        String appid = Constants.appID + "";
        String sign = signString(time);
        advService.getAdvList(time, appid, sign)
                .enqueue(new Callback<RespEntity<List<ADVEntity>>>() {
                    @Override
                    public void onResponse(Call<RespEntity<List<ADVEntity>>> call,
                            Response<RespEntity<List<ADVEntity>>> response) {
                        Log.i(TAG, "requestAdv onResponse" + response.isSuccessful());
                        if (response.isSuccessful() && response.body() != null) {
                            callback.onLoadSuccess(response.body().data);
                        } else {
                            callback.onLoadFailed("response not success");
                        }
                    }

                    @Override
                    public void onFailure(Call<RespEntity<List<ADVEntity>>> call, Throwable t) {
                        Log.i(TAG, "requestAdv onFailure" + t.getMessage());
                        callback.onLoadFailed("onFailure " + t.getMessage());
                    }
                });
    }

    public void requestAdv(final ICallback<List<ADVEntity>> callback) {
        Log.i(TAG, "requestAdv " + mHasApiRequested);
        if (mHasApiRequested) {
            _requestAdv(callback);
        } else {
            //
            requestApi(new ICallback<ApiEntity>() {
                @Override
                public void onLoadSuccess(ApiEntity apiEntity) {
                    _requestAdv(callback);
                }

                @Override
                public void onLoadFailed(String err) {
                    callback.onLoadFailed(err);
                }
            });
        }
    }

    WaterMarkEntity mWaterMarkEntity;

    public void requestWaterMark(final ICallback<WaterMarkEntity> callback) {
        if (mHasApiRequested) {
            if (mWaterMarkEntity == null) {
                IWatermarkService service = retrofit.create(IWatermarkService.class);
                String time = getTimeStamp();
                String appId = Constants.appID;
                String sign = signString(time);
                service.getWaterMark(time, appId, sign)
                        .enqueue(new Callback<RespEntity<WaterMarkEntity>>() {

                            @Override
                            public void onResponse(Call<RespEntity<WaterMarkEntity>> call,
                                    Response<RespEntity<WaterMarkEntity>> response) {
                                if (response.isSuccessful() && response.body() != null) {
                                    mWaterMarkEntity = response.body().data;
                                    callback.onLoadSuccess(mWaterMarkEntity);
                                } else {
                                    callback.onLoadFailed("response not success");
                                }
                            }

                            @Override
                            public void onFailure(Call<RespEntity<WaterMarkEntity>> call,
                                    Throwable t) {
                                callback.onLoadFailed("response onFailure " + t.getMessage());
                            }
                        });
            } else {
                callback.onLoadSuccess(mWaterMarkEntity);
            }
        } else {
            //
        }
    }

    public void requestProfile(String code,final ICallback<ProfileEntity> callback) {
        if (HttpClient.getInstance().hasApiRequested()) {
            IProfileService tagService = retrofit.create(IProfileService.class);
            String time = getTimeStamp();
            String appId = Constants.appID;
            String sign = signString(time);
            tagService.getProfile(time, appId, sign,code)
                    .enqueue(new Callback<RespEntity<ProfileEntity>>() {
                        @Override
                        public void onResponse(Call<RespEntity<ProfileEntity>> call,
                                               Response<RespEntity<ProfileEntity>> response) {
                            if (response.isSuccessful() && response.body() != null) {
                                callback.onLoadSuccess(response.body().data);
                            } else {
                                callback.onLoadFailed("response not success");
                            }
                        }

                        @Override
                        public void onFailure(Call<RespEntity<ProfileEntity>> call,
                                              Throwable t) {
                            callback.onLoadFailed("response onFailure " + t.getMessage());
                        }
                    });
        } else {
            //
        }
    }

    public void requestDeductVideo(String code,final ICallback<Integer> callback){
        if (HttpClient.getInstance().hasApiRequested()) {
            IDeductService deductService = retrofit.create(IDeductService.class);
            String time = getTimeStamp();
            String appId = Constants.appID;
            String sign = signString(time);
            deductService.getDeductResult(time, appId, sign,code)
                    .enqueue(new Callback<RespEntity<Integer>>() {
                        @Override
                        public void onResponse(Call<RespEntity<Integer>> call,
                                               Response<RespEntity<Integer>> response) {
                            if (response.isSuccessful() && response.body() != null) {
                                callback.onLoadSuccess(response.body().data);
                            } else {
                                callback.onLoadFailed("response not success");
                            }
                        }

                        @Override
                        public void onFailure(Call<RespEntity<Integer>> call,
                                              Throwable t) {
                            callback.onLoadFailed("response onFailure " + t.getMessage());
                        }
                    });
        } else {
            //
        }
    }

    public void requestCustomerEntity(final ICallback<List<CustomerEntity>> callback){
        if (HttpClient.getInstance().hasApiRequested()) {
            ICustomerService customerService = retrofit.create(ICustomerService.class);
            String time = getTimeStamp();
            String appId = Constants.appID;
            String sign = signString(time);
            customerService.getCustomerEntity(time, appId, sign)
                    .enqueue(new Callback<RespEntity<List<CustomerEntity>>>() {
                        @Override
                        public void onResponse(Call<RespEntity<List<CustomerEntity>>> call,
                                               Response<RespEntity<List<CustomerEntity>>> response) {
                            if (response.isSuccessful() && response.body() != null) {
                                callback.onLoadSuccess(response.body().data);
                            } else {
                                callback.onLoadFailed("response not success");
                            }
                        }

                        @Override
                        public void onFailure(Call<RespEntity<List<CustomerEntity>>> call,
                                              Throwable t) {
                            callback.onLoadFailed("response onFailure " + t.getMessage());
                        }
                    });
        } else {
            //
        }
    }

    public boolean hasApiRequested() {
        return mHasApiRequested;
    }
}
